﻿''' <summary>
''' 数据还原界面
''' </summary>
''' <remarks></remarks>
Public Class frmRestore

    ''' <summary>
    ''' 备份时 Mysqldump 返回的值
    ''' </summary>
    ''' <remarks></remarks>
    Private outputdata As StringBuilder

    ''' <summary>
    ''' 数据备份设置
    ''' </summary>
    ''' <remarks></remarks>
    Private sett As Setting

    ''' <summary>
    ''' 是否进行备份过
    ''' </summary>
    ''' <remarks></remarks>
    Public HasBackup As Boolean = True

    ''' <summary>
    ''' 备份日期
    ''' </summary>
    ''' <remarks></remarks>
    Private backupDate As Date

	''' <summary>
    ''' 备份时出现的错误信息
    ''' </summary>
    ''' <remarks></remarks>
    Private Shared ErrorData As StringBuilder
	
    ''' <summary>
    ''' 初始化还原窗体
    ''' </summary>
    ''' <param name="setting">数据库备份计划</param>
    ''' <remarks></remarks>
    Sub New(ByVal setting As Setting)

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        If (setting Is Nothing) Then
            Windows.Forms.MessageBox.Show("你没有备份过数据库，不能进行还原数据操作！", "系统提示", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
           
            HasBackup = False
        Else
            sett = setting
#If DEBUG Then

            If setting Is Nothing Then
                sett = New Setting()
                sett.FromDBName = "test"
                sett.ToDirectory = "C:/"
            End If

#End If
            ' 设置选择文件的默认目录
            Me.dlgFromFile.InitialDirectory = sett.ToDirectory

            ' 初始化控件
            InitControls()
        End If

    End Sub

    ''' <summary>
    ''' 初始化控件状态
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub InitControls()
        Me.btnRestore.Enabled = False
        Me.pbStatus.Visible = False
    End Sub

    ''' <summary>
    ''' 在界面上画分割线
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub frmRestore_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
        Dim p As System.Drawing.Pen = New Drawing.Pen(Drawing.Color.Silver, 1)
        e.Graphics.DrawLine(p, 12, 91, 384, 91)
        e.Graphics.DrawLine(Drawing.Pens.SlateGray, 12, 90, 384, 90)
    End Sub

    ''' <summary>
    '''  进行备份
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub btnRestore_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRestore.Click

        Me.DialogResult = Windows.Forms.DialogResult.None

        If (Windows.Forms.MessageBox.Show("确认要还原数据么？", "系统提示", Windows.Forms.MessageBoxButtons.YesNo, _
                                        Windows.Forms.MessageBoxIcon.Question, _
                                        Windows.Forms.MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.No) Then

            Exit Sub
        End If

        ' 检测文件名称是否正确
        If (CheckFileName(Me.dlgFromFile.FileName)) Then
            '' 开启显示
            Me.pbStatus.Value = 0
            Me.pbStatus.Visible = True

            ISFinished = False
            Timer1.Start()

            '还原操作
            ' RestoreDatabase(Me.dlgFromFile.FileName)
            Dim th As New Thread(AddressOf frmRestore.RestoreDatabase)

            th.Start(Me.dlgFromFile.FileName)

            ''====================================
            '' 恢复状态
            ' Me.pbStatus.Value = 100
            '  Me.pbStatus.Visible = False
            '  Timer1.Stop()
            '  Me.btnRestore.Enabled = False

            '   Me.DialogResult = Windows.Forms.DialogResult.OK
        End If

    End Sub


    Private Shared ISFinished As Boolean = False

    ''' <summary>
    ''' 还原数据库
    ''' </summary>
    ''' <param name="strfile">用于还原的文件</param>
    ''' <remarks></remarks>
    Public Shared Sub RestoreDatabase(ByVal strfile As Object)
        If Not (TypeOf strfile Is String) Then
            Exit Sub
        End If
        Dim prc As Process = New Process()
        Dim pInfo As ProcessStartInfo = New ProcessStartInfo()


        Dim bkCmd As StringBuilder = New StringBuilder
        bkCmd.Append(" /c mysql ")
        bkCmd.AppendFormat(" -u{0} -p{1} ", Encryptor.Decrypt(DBConfig.DBUserName), Encryptor.Decrypt(DBConfig.DBPassword))
        '' ====================================
        '' 添加参数
        bkCmd.AppendFormat(" {0} < ""{1}"" ", Encryptor.Decrypt(DBConfig.DatabaseName), strfile.Replace("\", "/"))

        pInfo.WorkingDirectory = DBConfig.DBDirectory
        pInfo.FileName = "cmd.exe"
        pInfo.Arguments = bkCmd.ToString()
        pInfo.CreateNoWindow = True
        pInfo.UseShellExecute = False
        pInfo.RedirectStandardOutput = False
        pInfo.RedirectStandardError = True
       
       '   AddHandler prc.OutputDataReceived, AddressOf OutPutHandler
        AddHandler prc.ErrorDataReceived, AddressOf ErrorHandler

        '   Outputdata = New StringBuilder()
        ErrorData = New StringBuilder()
		
#If DEBUG Then
        Dim st As Date = Date.Now
        System.Diagnostics.Debug.Print("Restore At " + Date.Now.ToString("yyyyMMdd HHmmss"))
		 System.Diagnostics.Debug.Print(ErrorData.ToString())
#End If
        prc.StartInfo = pInfo
        prc.Start()

        '   prc.BeginOutputReadLine()
		prc.BeginErrorReadLine()
		
        prc.WaitForExit()
#If DEBUG Then
        '' 查看返回的输出
        '  System.Diagnostics.Debug.Print(outputdata.ToString())
#End If
        prc.Close()
#If DEBUG Then
        System.Diagnostics.Debug.Print("Restore Finsihed " + Date.Now.ToString("yyyyMMdd HHmmss"))
        System.Diagnostics.Debug.Print("Restore Use times: " + Date.Now.Subtract(st).ToString())
#End If
        ISFinished = True
    End Sub

    ''' <summary>
    ''' 处理异步输出结果
    ''' </summary>
    ''' <param name="outline">输出参数</param>
    ''' <remarks></remarks>
    Private Sub OutPutHandler(ByVal sendingPro As Object, ByVal outline As DataReceivedEventArgs)
        'outputdata.Append(outline.Data)
    End Sub

    ''' <summary>
    ''' 接收错误信息
    ''' </summary>    
    ''' <remarks></remarks>
    Private Shared Sub ErrorHandler(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
        ErrorData.Append(e.Data)
    End Sub
	
    ''' <summary>
    ''' 检测文件名称是否正确
    ''' </summary>
    ''' <param name="filename">文件名称</param>
    ''' <returns>文件名称正确返回true；否则返回false。</returns>
    ''' <remarks>检测过程更新lblMessage的内容</remarks>
    Private Function CheckFileName(ByVal filename As String) As Boolean

        lblMessage.Text = ""

        filename = filename.Replace("\", "/")
#If DEBUG Then
        System.Diagnostics.Debug.Print(filename)
#End If

        Dim strName = filename.Substring(filename.LastIndexOf("/") + 1)
        Dim strdb = Encryptor.Decrypt(sett.FromDBName)
        If strName.Contains(strdb) Then
            Try
                ' 分析备份时间
                Dim dt As String = strName.Remove(0, strdb.Length)
                Dim bkDate As Date
                ''YYYYMMDD_hhmmss
                bkDate = New Date(Integer.Parse(dt.Substring(0, 4)), Integer.Parse(dt.Substring(4, 2)), Integer.Parse(dt.Substring(6, 2)), _
                                              Integer.Parse(dt.Substring(9, 2)), Integer.Parse(dt.Substring(11, 2)), Integer.Parse(dt.Substring(13, 2)))

                Me.lblMessage.Text = String.Format("你选择的备份文件备份时间为： {0} ", bkDate.ToString("yyyy-MM-dd hh:mm:ss"))
                backupdate = bkDate
                Me.txtFromFile.Text = filename.Replace("/", "\")
            Catch ex As Exception
                Windows.Forms.MessageBox.Show("选择的文件不正确！不能进行还原操作。", "错误", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Error)

                Return False
            End Try
        Else
            Windows.Forms.MessageBox.Show("选择的文件不正确！不能进行还原操作。", "错误", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Error)
            Return False
        End If

        Return True
    End Function

    ''' <summary>
    ''' 选择用于还原的备份文件
    ''' </summary>  
    ''' <remarks></remarks>
    Private Sub btnSelectFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSelectFile.Click
        If (Me.dlgFromFile.ShowDialog() = Windows.Forms.DialogResult.OK) Then

            Me.btnRestore.Enabled = False

            ' 检测文件名
            If (CheckFileName(Me.dlgFromFile.FileName)) Then

                Me.btnRestore.Enabled = True
            End If
        End If
    End Sub

    Private Delegate Sub UpdateStatus()


    Private Sub UpdateBr()
        If Me.pbStatus.Value < 100 Then
            Me.pbStatus.Value += 10
        Else
            Me.pbStatus.Value = 0
        End If
        Me.pbStatus.Refresh()
    End Sub

    ''' <summary>
    ''' 计时器更新 pbStatus
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If (ISFinished) Then
            ISFinished = False
            Timer1.Stop()

            Dim cm As ConfigurationManager = New ConfigurationManager
            cm.UpdateRestore(backupDate.ToString("yyyy-MM-dd HH:mm:ss"))

            If (ErrorData.Length > 0) Then
                Windows.Forms.MessageBox.Show("还原失败！" + Environment.NewLine + "检查备份文件，在进行还原操作。", "系统提示", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Error)
                Me.DialogResult = Windows.Forms.DialogResult.Cancel
            Else

                Windows.Forms.MessageBox.Show("还原成功！" + Environment.NewLine + "请重启系统，系统进行更新配置。", "系统提示", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Information)
                Me.DialogResult = Windows.Forms.DialogResult.OK
            End If

            Return
        End If

        If (pbStatus.InvokeRequired) Then
            Me.pbStatus.Invoke(New UpdateStatus(AddressOf UpdateBr))
        Else
            UpdateBr()
        End If


    End Sub


    '    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
    '#If DEBUG Then
    '        Windows.Forms.MessageBox.Show("sd")
    '#End If
    '    End Sub

    '    Private Sub frmRestore_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
    '        If (sett Is Nothing) Then
    '            Me.CancelButton.PerformClick()
    '        End If
    '    End Sub
End Class